package com.example.appusagestats.manager

import android.app.AppOpsManager
import android.app.usage.UsageEvents
import android.app.usage.UsageStatsManager
import android.content.Context
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
import android.os.Build
import android.provider.Settings
import com.example.appusagestats.model.AppUsageInfo
import com.example.appusagestats.model.TimeSlot
import com.example.appusagestats.model.UsageEvent
import java.util.*

class AppUsageStatsManager(private val context: Context) {

    private val usageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
    private val packageManager = context.packageManager

    fun hasUsageStatsPermission(): Boolean {
        val appOps = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
        val mode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            appOps.unsafeCheckOpNoThrow(
                AppOpsManager.OPSTR_GET_USAGE_STATS,
                android.os.Process.myUid(),
                context.packageName
            )
        } else {
            appOps.checkOpNoThrow(
                AppOpsManager.OPSTR_GET_USAGE_STATS,
                android.os.Process.myUid(),
                context.packageName
            )
        }
        return mode == AppOpsManager.MODE_ALLOWED
    }

    fun requestUsageStatsPermission() {
        val intent = Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS)
        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
        context.startActivity(intent)
    }

    fun getTodayAppUsageStats(): List<AppUsageInfo> {
        if (!hasUsageStatsPermission()) {
            return emptyList()
        }

        val calendar = Calendar.getInstance()
        calendar.set(Calendar.HOUR_OF_DAY, 0)
        calendar.set(Calendar.MINUTE, 0)
        calendar.set(Calendar.SECOND, 0)
        calendar.set(Calendar.MILLISECOND, 0)
        val startTime = calendar.timeInMillis

        calendar.add(Calendar.DAY_OF_MONTH, 1)
        val endTime = calendar.timeInMillis

        return getAppUsageStats(startTime, endTime)
    }

    fun getAppUsageStatsByTimeSlot(timeSlot: TimeSlot): List<AppUsageInfo> {
        if (!hasUsageStatsPermission()) {
            return emptyList()
        }

        val calendar = Calendar.getInstance()
        calendar.set(Calendar.HOUR_OF_DAY, timeSlot.startHour)
        calendar.set(Calendar.MINUTE, 0)
        calendar.set(Calendar.SECOND, 0)
        calendar.set(Calendar.MILLISECOND, 0)
        val startTime = calendar.timeInMillis

        calendar.set(Calendar.HOUR_OF_DAY, timeSlot.endHour)
        val endTime = calendar.timeInMillis

        return getAppUsageStats(startTime, endTime)
    }

    private fun getAppUsageStats(startTime: Long, endTime: Long): List<AppUsageInfo> {
        val usageStats = usageStatsManager.queryUsageStats(
            UsageStatsManager.INTERVAL_DAILY,
            startTime,
            endTime
        )

        val appUsageMap = mutableMapOf<String, AppUsageInfo>()

        for (stat in usageStats) {
            if (stat.totalTimeInForeground > 0) {
                val packageName = stat.packageName
                val appInfo = getAppInfo(packageName)
                
                if (appInfo != null) {
                    val usageEvents = getUsageEvents(packageName, startTime, endTime)
                    appUsageMap[packageName] = AppUsageInfo(
                        packageName = packageName,
                        appName = appInfo.loadLabel(packageManager).toString(),
                        appIcon = appInfo.loadIcon(packageManager),
                        totalTimeInForeground = stat.totalTimeInForeground,
                        usageEvents = usageEvents
                    )
                }
            }
        }

        return appUsageMap.values.sortedByDescending { it.totalTimeInForeground }
    }

    private fun getAppInfo(packageName: String): ApplicationInfo? {
        return try {
            packageManager.getApplicationInfo(packageName, 0)
        } catch (e: PackageManager.NameNotFoundException) {
            null
        }
    }

    private fun getUsageEvents(packageName: String, startTime: Long, endTime: Long): List<UsageEvent> {
        val events = mutableListOf<UsageEvent>()
        val usageEvents = usageStatsManager.queryEvents(startTime, endTime)
        
        var currentStartTime: Long? = null
        
        while (usageEvents.hasNextEvent()) {
            val event = UsageEvents.Event()
            usageEvents.getNextEvent(event)
            
            if (event.packageName == packageName) {
                when (event.eventType) {
                    UsageEvents.Event.MOVE_TO_FOREGROUND -> {
                        currentStartTime = event.timeStamp
                    }
                    UsageEvents.Event.MOVE_TO_BACKGROUND -> {
                        if (currentStartTime != null) {
                            val duration = event.timeStamp - currentStartTime!!
                            if (duration > 0) {
                                events.add(UsageEvent(
                                    startTime = currentStartTime!!,
                                    endTime = event.timeStamp,
                                    duration = duration
                                ))
                            }
                            currentStartTime = null
                        }
                    }
                }
            }
        }
        
        return events.sortedBy { it.startTime }
    }
} 